!pr0
Making a Map of Differences................Bob Sander-Cederlof

Many times I have had two versions of the same program, and wondered where the differences might be.

For example, where are the differences between DOS 3.2 and 3.3, or between the various releases of DOS 3.3?  And now that Apple has sent out some pre-releases of a new set of CDEF ROMs for the //e, where are the differences between these and the current //e ROMs?

I have always used the monitor V command to find them.  By doing it a small piece at a time, I can pinpoint the changes.  Then I turn on my printer and use the L command to document the new version wherever there are differences.  But the piecemeal use of the V command wastes a lot of time.  I wish I had some way of printing a complete map of all the differences....

What if I had a command which would compare two areas of memory, and print a map of differences?  I could use a "." to represent matching locations, and a "*" to represent those that do not match.  I could print either 32 or 64 per line:  32 on a 40-column screen, 64 on an 80-column screen or printer.  Then I could tell at a glance where all changes had occurred!

I looked at the October 1981 issue of AAL to find out how to use the control-Y monitor command to add a new monitor feature.  Then I looked in the listing of the monitor ROM (in my old "red" Apple Reference Manual) at the code for the V command and the command which prints a range of memory.

The program on the next page is the result.

Lines 1150-1190 set up the monitor control-Y vector.  Booting DOS stores a branch which effectively makes the control-Y command do nothing.  Storing the address of a real program there allows you to add your own commands to the monitor.  Once installed, typing a control-Y into the monitor will execute the program named DIFFERENCES.

When we get there, if we typed a full length monitor command of the form "address1<address2.address3^Y" (by "^Y" I mean control-Y), all three of the addresses will have been converted to binary and stored in some standard locations.  Address1 will be in $42 and $43, address2 in $3C and $3D, and address3 in $3E and $3F.  We will interpret the addresses to mean to compare the block of memory beginning at address1 with the block running from address2 through address3.

Line 1220 prints a carriage return, the current address value in $3C and $3D, and a dash.  Lines 1230-1280 compare the bytes at corresponding positions in the two blocks of memory, and select either a "." or a "*" accordingly.  Line 1290 prints the selected character.

Lines 1300-1310 increment the two base addresses to point to the next byte in both memory blocks.  The new address2 is also compared to address3 to see if we are finished yet.
Lines 1320-1350 check to see if we have printed all 32 on the current screen line.  If not, back to .1 to print the next one.  Otherwise, all the way back to print a new address and dash, starting a new line.  If you want 64 bytes per line, change the mask in line 1330 from #$1F to #$3F.  You might want to have the program check to see whether 80-columns is turned on or not, and automatically select #$1F or #$3F accordingly.  You could also check to see if the output hook at $36, 37 is pointing at a printer, and use the longer lines.

Experiment.  You'll learn a lot and have a lot of fun at the same time!
